export default class Where {
	constructor(ctx) {
		this.$dx = ctx;
		this.dbCmd = ctx.db.command;
	}
	#resetArrayWhere = function(arr) {
		let where = {};
		for (let item of arr.entries(arr)) {
			Object.assign(where, this.#resetObjectWhere(item));
		}
		return where;
	};
	#resetStringWhere = function(key, op = '=', val) {
		let where = {},
			array = [];
		switch (op) {
			case '=':
			case 'eq':
				where[key] = this.dbCmd.eq(val);
				break;
			case '!=':
			case '<>':
			case 'neq':
				where[key] = this.dbCmd.neq(val);
				break;
			case '>':
			case 'gt':
				where[key] = this.dbCmd.gt(val);
				break;
			case '>=':
			case 'gte':
				where[key] = this.dbCmd.gte(val);
				break;
			case 'between':
				where[key] = this.dbCmd.gte(val[0]).and(this.dbCmd.lte(val[1]));
				break;
			case '<':
			case 'lt':
				where[key] = this.dbCmd.lt(val);
				break;
			case '<=':
			case 'lte':
				where[key] = this.dbCmd.lte(val);
				break;
			case 'in':
			case 'IN':
				array = [];
				if (typeof val === 'string') {
					array = val.indexOf(',') != -1 ? val.split(',') : [val];
				}
				if (Array.isArray(val)) {
					array = val;
				}
				where[key] = this.dbCmd.in(array);
				break;
			case 'nin':
			case 'NIN':
				array = [];
				if (typeof val == 'string') {
					array = val.indexOf(',') != -1 ? val.split(',') : [val];
				}
				if (Array.isArray(val)) {
					array = val;
				}
				where[key] = this.dbCmd.nin(array);
				break;
			case 'like':
				if (typeof val === 'string') {
					where[key] = new RegExp('' + val, 'i');
				} else if (this.$dx.utils.isArray(val)) {
					// 正则或
					where[key] = new RegExp(val.join('|'), 'i');
				}
				break;
			case 'like%':
				where[key] = new RegExp('^' + val, 'i');
				break;
			case '%like':
				where[key] = new RegExp(val + '^', 'i');
				break;
			case "contain":
				array = Array.isArray(val) ? [...val] : [val];
				where[key] = this.dbCmd.all(array);
				break;
			case "contains":
				(array = []),
				"string" == typeof val &&
					(array = -1 != val.indexOf(",") ? val.split(",") : [val]),
					Array.isArray(val) && (array = val),
					(where[key] = this.dbCmd.elemMatch(this.dbCmd.in(array)));
				break;
			case 'is_empty':
				let ors = [];
				if (!Array.isArray(val)) {
					val = [val];
				}
				for (let item of val) {
					switch (item) {
						case 'null':
						case null:
							ors.push(this.dbCmd.eq(null));
							break;
						case 'empty':
							ors.push(this.dbCmd.eq(''));
							break;
						case '0':
						case 0:
							ors.push(this.dbCmd.eq(0));
							break;
						case 'exists':
							ors.push(this.dbCmd.exists(false));
							break;
						case 'false':
						case false:
							ors.push(this.dbCmd.eq(false));
							break;
					}
				}
				where[key] = this.dbCmd.or(ors);
				break;
		}
		return where;
	};
	//对象的
	#resetObjectWhere = function(param) {
		let where = {};
		for (let [key, item] of Object.entries(param)) {
			if (this.$dx.utils.isArray(item) && item.length == 2) {
				Object.assign(where, this.#resetStringWhere(key, item[0], item[1]));
			} else if (this.$dx.utils.isObject(item) && typeof item.op === 'string' && item.op) {
				Object.assign(where, this.#resetStringWhere(key, item.op, item.value));
			} else {
				Object.assign(where, this.#resetStringWhere(key, '=', item));
			}
		}
		return where;
	};
	getWhere(args) {
		if (!args) return {};
		switch (args.length) {
			case 1:
				//数组[{},{}] 对象
				if (this.$dx.utils.isArray(args[0])) {
					return this.#resetArrayWhere(args[0]);
				}
				//对象{_id:1,age:2,name:['like','kk']}
				if (this.$dx.utils.isObject(args[0])) {
					return this.#resetObjectWhere(args[0]);
				}
				break;
			case 2: //等于的
				//直接查询，不需转换
				if (this.$dx.utils.isObject(args[0]) && args[1] === true) {
					return args[0];
				}
				return this.#resetStringWhere(args[0], '=', args[1]);
			case 3: //带操作符
				return this.#resetStringWhere(...args);
		}
		return {};
	}
	toGetWhere(args) {
		let whereParam = [];
		for (let item of args) {
			whereParam.push(this.getWhere(item));
		}
		return whereParam;
	}
}